package com.zhj.wapper;

import com.zhj.enums.JavaCompileType;
import com.zhj.exception.DynamicCompileException;
import com.zhj.wapper.java.JavaCompile;
import com.zhj.wapper.java.JavaCompilerFactory;

import org.apache.commons.lang3.StringUtils;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.util.Map;
import java.util.concurrent.locks.Lock;

import javax.script.ScriptException;


public class DynamicJarCompileWrapper implements DynamicCompileWrapper<JavaCompile> {

    public static final String engineName = "java";

    /**
     * 根据脚本来创建class类并且执行main方法
     * @param eval 脚本
     * @param params
     * @return
     * @throws ScriptException
     */
    @Override
    public Object execFunction(String eval, Map<String, Object> params) throws DynamicCompileException {
        JavaCompile javaCompile = getScriptEngine(eval);
        try {
            javaCompile.runMainMethod((String[]) buildMapToArray(params));
        } catch (Exception e) {
            throw DynamicCompileException.newInstance(e.getMessage());
        }
        return null;
    }

    /**
     * 根据对应执行函数
     * @param eval
     * @param methodName
     * @param params
     * @return
     * @throws DynamicCompileException
     */
    @Override
    public Object execFunctionForMethodName(String eval, String methodName, Map<String, Object> params) throws DynamicCompileException {
        JavaCompile javaCompile = this.getScriptEngine(eval);
        Object result = null;
        try {
            result = javaCompile.runMethod(methodName, buildMapToArray(params));
        } catch (Exception e) {
            throw DynamicCompileException.newInstance(e.getMessage());
        }
        return result;
    }
    /**
     *
     * @param path
     * @param methodName
     * @param params 如果是jar包启动，默认会找参数中 key为class的启动类
     * @return
     * @throws DynamicCompileException
     */
    @Override
    public Object execFunctionForFile(String path, String methodName, Map<String, Object> params) throws DynamicCompileException {
        File file = new File(path);
        if (!file.exists()) {
            throw new DynamicCompileException("文件路径:" + path + "不存在");
        }
        String fileName = file.getName();
        String suffix = StringUtils.substringAfterLast(fileName, ".");
        if (!file.isDirectory() && !JavaCompileType.JAR.toString().equalsIgnoreCase(suffix)) {
            throw new DynamicCompileException("当前路径不是jar包");
        }
        //获取到所有class名称
        String[] classList = file.list();
        return null;
    }

    /**
     * 根据jar包获取
     * @param file
     * @param className
     * @return
     * @throws DynamicCompileException
     */
    private JavaCompile buildJavaCompileForJar(File file, String className) throws DynamicCompileException {
        if (file.isFile()) {
            return buildJavaCompileForFile(file);
        }
        return null;
    }

    /**
     *
     * @param file
     * @return
     * @throws DynamicCompileException
     */
    private JavaCompile buildJavaCompileForFile(File file) throws DynamicCompileException {
        JavaCompile javaCompile;
        try {
            FileInputStream inputStream = new FileInputStream(file);
            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
            byte[] bytes = new byte[1024];
            int tempChar;
            while ((tempChar = inputStream.read(bytes)) != -1) {
                outputStream.write(bytes, 0, tempChar);
            }
            String sourceCode = outputStream.toString();
            javaCompile = getScriptEngine(sourceCode);
        } catch (Exception e) {
            throw DynamicCompileException.newInstance(e.getMessage());
        }
        return javaCompile;
    }

    /**
     *
     * @param scriptName 脚本代码
     * @return
     */
    @Override
    public JavaCompile getScriptEngine(String scriptName) {
        return JavaCompilerFactory.getCompiler(scriptName);
    }

    @Override
    public Lock getLock() {
        return null;
    }

    /**
     * 将map转换为数组
     * @param params
     * @return
     */
    private Object[] buildMapToArray(Map<String, Object> params) {
        return params.values().toArray();
    }
    /**
     * 创建实例
     * @return
     */
    public static DynamicCompileWrapper<JavaCompile> createInstance() {
        return new DynamicJarCompileWrapper();
    }

}
